package com.luo.backend.service;

import com.luo.backend.dto.AdminUserDetailResponse;
import com.luo.backend.dto.AdminUserListResponse;
import com.luo.backend.entity.*;
import com.luo.backend.repository.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.Predicate;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 管理员-用户管理服务
 */
@Service
public class AdminUserService {
    
    @Autowired
    private UserRepository userRepository;
    
    @Autowired
    private OrderRepository orderRepository;
    
    @Autowired
    private UserAddressRepository addressRepository;
    
    @Autowired
    private GroupBuyingParticipantRepository participantRepository;
    
    @Autowired
    private MerchantRepository merchantRepository;
    
    /**
     * 获取用户列表
     */
    public AdminUserListResponse getUserList(
            Integer page, 
            Integer size, 
            String keyword,
            String role,
            Integer status,
            String sortBy,
            String sortOrder) {
        
        // 设置默认值
        if (page == null || page < 1) page = 1;
        if (size == null || size < 1) size = 10;
        if (sortBy == null) sortBy = "createdAt";
        if (sortOrder == null) sortOrder = "desc";
        
        // 创建分页和排序
        Sort sort = sortOrder.equalsIgnoreCase("asc") ? 
                    Sort.by(sortBy).ascending() : 
                    Sort.by(sortBy).descending();
        Pageable pageable = PageRequest.of(page - 1, size, sort);
        
        // 构建查询条件
        Specification<User> spec = (root, query, cb) -> {
            List<Predicate> predicates = new ArrayList<>();
            
            // 排除admin用户自己
            predicates.add(cb.notEqual(root.get("role"), "admin"));
            
            // 关键词搜索
            if (keyword != null && !keyword.trim().isEmpty()) {
                String likePattern = "%" + keyword + "%";
                predicates.add(cb.or(
                    cb.like(root.get("username"), likePattern),
                    cb.like(root.get("email"), likePattern),
                    cb.like(root.get("phone"), likePattern)
                ));
            }
            
            // 角色筛选
            if (role != null && !role.trim().isEmpty()) {
                predicates.add(cb.equal(root.get("role"), role));
            }
            
            // 状态筛选
            if (status != null) {
                predicates.add(cb.equal(root.get("status"), status));
            }
            
            return cb.and(predicates.toArray(new Predicate[0]));
        };
        
        // 查询数据
        Page<User> userPage = userRepository.findAll(spec, pageable);
        
        // 构建响应
        AdminUserListResponse response = new AdminUserListResponse();
        
        // 设置用户列表
        List<AdminUserListResponse.UserItem> items = userPage.getContent().stream()
            .map(this::convertToUserItem)
            .collect(Collectors.toList());
        response.setItems(items);
        
        // 设置分页信息
        response.setPagination(new AdminUserListResponse.Pagination(
            page, 
            size, 
            userPage.getTotalElements()
        ));
        
        // 设置统计信息
        response.setStatistics(getUserStatistics());
        
        return response;
    }
    
    /**
     * 获取用户详情
     */
    public AdminUserDetailResponse getUserDetail(Long userId) {
        Optional<User> userOpt = userRepository.findById(userId);
        if (!userOpt.isPresent()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        AdminUserDetailResponse response = new AdminUserDetailResponse();
        
        // 基本信息
        response.setId(user.getId());
        response.setUsername(user.getUsername());
        response.setEmail(user.getEmail());
        response.setPhone(user.getPhone());
        response.setRealName(user.getRealName());
        response.setAvatar(user.getAvatar());
        response.setGender(user.getGender());
        response.setRole(user.getRole());
        response.setStatus(user.getStatus());
        response.setStatusText(user.getStatus() == 1 ? "正常" : "已禁用");
        response.setMerchantId(user.getMerchantId());
        response.setLastLoginAt(user.getLastLoginAt());
        response.setCreatedAt(user.getCreatedAt());
        response.setUpdatedAt(user.getUpdatedAt());
        
        // 商家名称
        if (user.getMerchantId() != null) {
            merchantRepository.findById(user.getMerchantId()).ifPresent(merchant -> {
                response.setMerchantName(merchant.getName());
            });
        }
        
        // 统计信息
        response.setStatistics(getUserDetailStatistics(userId));
        
        // 最近订单（最近5条）
        response.setRecentOrders(getRecentOrders(userId, 5));
        
        // 地址列表
        response.setAddresses(getUserAddresses(userId));
        
        return response;
    }
    
    /**
     * 删除用户
     */
    @Transactional
    public void deleteUser(Long userId) {
        Optional<User> userOpt = userRepository.findById(userId);
        if (!userOpt.isPresent()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        
        // 不能删除管理员
        if ("admin".equals(user.getRole())) {
            throw new RuntimeException("不能删除管理员账号");
        }
        
        // 检查未完成订单
        List<String> pendingStatuses = Arrays.asList("pending", "paid", "preparing", "shipping");
        long pendingOrderCount = orderRepository.countByUserIdAndStatusIn(userId, pendingStatuses);
        if (pendingOrderCount > 0) {
            throw new RuntimeException("该用户有未完成的订单，无法删除");
        }
        
        // 删除用户（级联删除会自动处理关联数据）
        userRepository.deleteById(userId);
    }
    
    /**
     * 更新用户状态
     */
    @Transactional
    public void updateUserStatus(Long userId, Integer status) {
        Optional<User> userOpt = userRepository.findById(userId);
        if (!userOpt.isPresent()) {
            throw new RuntimeException("用户不存在");
        }
        
        User user = userOpt.get();
        
        // 不能禁用管理员
        if ("admin".equals(user.getRole())) {
            throw new RuntimeException("不能禁用管理员账号");
        }
        
        user.setStatus(status);
        userRepository.save(user);
    }
    
    /**
     * 转换为UserItem
     */
    private AdminUserListResponse.UserItem convertToUserItem(User user) {
        AdminUserListResponse.UserItem item = new AdminUserListResponse.UserItem();
        item.setId(user.getId());
        item.setUsername(user.getUsername());
        item.setEmail(user.getEmail());
        item.setPhone(user.getPhone());
        item.setRealName(user.getRealName());
        item.setAvatar(user.getAvatar());
        item.setGender(user.getGender());
        item.setRole(user.getRole());
        item.setStatus(user.getStatus());
        item.setStatusText(user.getStatus() == 1 ? "正常" : "已禁用");
        item.setMerchantId(user.getMerchantId());
        item.setLastLoginAt(user.getLastLoginAt());
        item.setCreatedAt(user.getCreatedAt());
        
        // 商家名称
        if (user.getMerchantId() != null) {
            merchantRepository.findById(user.getMerchantId()).ifPresent(merchant -> {
                item.setMerchantName(merchant.getName());
            });
        }
        
        // 订单数量
        long orderCount = orderRepository.countByUserId(user.getId());
        item.setOrderCount(orderCount);
        
        // 总消费金额（只有customer角色才有）
        if ("customer".equals(user.getRole())) {
            BigDecimal totalSpent = orderRepository.sumTotalAmountByUserIdAndStatus(
                user.getId(), 
                "delivered"
            );
            item.setTotalSpent(totalSpent != null ? totalSpent : BigDecimal.ZERO);
        }
        
        return item;
    }
    
    /**
     * 获取用户统计信息
     */
    private AdminUserListResponse.Statistics getUserStatistics() {
        AdminUserListResponse.Statistics stats = new AdminUserListResponse.Statistics();
        
        stats.setTotalUsers(userRepository.countByRoleNot("admin"));
        stats.setCustomerCount(userRepository.countByRole("customer"));
        stats.setMerchantCount(userRepository.countByRole("merchant"));
        stats.setActiveCount(userRepository.countByStatusAndRoleNot(1, "admin"));
        stats.setDisabledCount(userRepository.countByStatusAndRoleNot(0, "admin"));
        
        return stats;
    }
    
    /**
     * 获取用户详情统计
     */
    private AdminUserDetailResponse.UserStatistics getUserDetailStatistics(Long userId) {
        AdminUserDetailResponse.UserStatistics stats = new AdminUserDetailResponse.UserStatistics();
        
        stats.setOrderCount(orderRepository.countByUserId(userId));
        
        BigDecimal totalSpent = orderRepository.sumTotalAmountByUserIdAndStatus(userId, "delivered");
        stats.setTotalSpent(totalSpent != null ? totalSpent : BigDecimal.ZERO);
        
        stats.setAddressCount(addressRepository.countByUserId(userId));
        stats.setGroupBuyingCount(participantRepository.countByUserId(userId));
        stats.setCancelledOrderCount(orderRepository.countByUserIdAndStatus(userId, "cancelled"));
        stats.setRefundedOrderCount(orderRepository.countByUserIdAndStatus(userId, "refunded"));
        
        return stats;
    }
    
    /**
     * 获取最近订单
     */
    private List<AdminUserDetailResponse.RecentOrder> getRecentOrders(Long userId, int limit) {
        Pageable pageable = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "createdAt"));
        List<Order> orders = orderRepository.findByUserId(userId, pageable);
        
        return orders.stream().map(order -> {
            AdminUserDetailResponse.RecentOrder recentOrder = new AdminUserDetailResponse.RecentOrder();
            recentOrder.setId(order.getId());
            recentOrder.setOrderNo(order.getOrderNo());
            recentOrder.setMerchantName(order.getMerchantName());
            recentOrder.setTotalAmount(order.getTotalAmount());
            recentOrder.setStatus(order.getStatus());
            recentOrder.setStatusText(getOrderStatusText(order.getStatus()));
            recentOrder.setCreatedAt(order.getCreatedAt());
            return recentOrder;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取用户地址
     */
    private List<AdminUserDetailResponse.UserAddress> getUserAddresses(Long userId) {
        List<com.luo.backend.entity.UserAddress> addresses = 
            addressRepository.findByUserIdOrderByIsDefaultDescCreatedAtDesc(userId);
        
        return addresses.stream().map(address -> {
            AdminUserDetailResponse.UserAddress userAddress = new AdminUserDetailResponse.UserAddress();
            userAddress.setId(address.getId());
            userAddress.setName(address.getName());
            userAddress.setPhone(address.getPhone());
            userAddress.setFullAddress(
                address.getProvince() + " " + 
                address.getCity() + " " + 
                address.getDistrict() + " " + 
                address.getAddress()
            );
            userAddress.setIsDefault(address.getIsDefault() != null && address.getIsDefault());
            return userAddress;
        }).collect(Collectors.toList());
    }
    
    /**
     * 获取订单状态文本
     */
    private String getOrderStatusText(String status) {
        switch (status) {
            case "pending": return "待支付";
            case "paid": return "已支付";
            case "preparing": return "准备中";
            case "shipping": return "配送中";
            case "delivered": return "已送达";
            case "cancelled": return "已取消";
            case "refunded": return "已退款";
            default: return status;
        }
    }
}

